上一课时,我讲解了如何更好地利用多个测试环境。本课时,我来讲解下如何构建持续交付工具链。
持续交付在上一篇文章中已经提到,它是指所有开发人员始终让 Master 分支保持可随时发布的状态,根据实际需要来判断是否进行一键式发布。而工具链(Tool Chain)通常是指一系列工具,它们按照一定的逻辑顺序运行,最终完成一件比较复杂的事情。
因此,持续交付工具链是帮助我们把持续交付进行落地的工具集合或自动化平台,它可以固化产品交付过程中的各个环节,实现自动化地构建、部署、测试、输出报告等工作。如下图所示。
持续交付示意图
构建持续交付工具链需要考虑哪些内容?
通过上面的描述,不难看出,构建持续交付工具链涉及如下工作。
现阶段持续集成和持续交付思想已经盛行起来,绝大多数的公司和团队能够认识到这种变化的重要性,因此组织方面的支持通常没有太大问题,但需要考虑落地的成本。因此,对于持续交付工具链的建设,可以借鉴常规的产品研发项目,使用小步快跑的方式,以“先有后优”的心态建设。如以下措施。
在产品研发交付过程中,不外乎有如下几个方面:代码&配置管理、构建&部署自动化、各种测试、反馈相关等内容。
通常来说,代码用成熟的工具管理起来的成本不高,比如常见的代码管理工具 GitHub、Atlassian Stash、GitLab 等。但在配置方面,常常有比较明显的问题,需要将配置进行统一化、自动化地管理。
在构建方面,比较推荐的是 Maven,它的“惯例胜于配置”的原则,使你只要按它指定的方式组织代码,就可以使用一条命令执行所有的构建、部署、测试和发布任务。而且它能自动管理项目间的依赖,这对于构建持续交付来说太友好了。
环境部署则需要能够对测试环境、预发布环境、生产环境的修改用自动化来完成。如果你还在以手工的方式远程登录到这些环境上执行部署工作,那就太 out 了。现阶段将部署完全脚本化已不存在任何技术难度。如果需要部署多台机器,充其量就是先分发到这些机器上,再在这些机器的本地执行部署脚本。
在没有持续集成和持续交付建设的团队里,测试环节通常比较滞后,且人工占比较高,这无疑给项目带来比较大的质量风险。因此,在测试环节的一个非常重要的策略是要尽可能地把各种测试过程自动化,且覆盖度和稳定性达到一定要求。
整个测试过程不仅有静态测试,也有动态测试。静态测试中的各类文档评审,比较难以自动化,但静态代码检查通常有现成的工具,比如最流行的 Sonar。动态测试包含了功能测试(微服务架构的分层测试)和非功能测试(性能测试、安全性测试),可以针对这些类型的测试进行自动化的改造。比如使用 Spring Cloud Contract 和 Pact 可以进行微服务的契约测试,使用 Jmeter 以非 GUI 的方式做性能测试、使用 SQLmap 检测诸如 SQL 注入的安全问题。自动化建设的投入一定要遵循“测试金字塔”,努力提升单元测试自动化的比重,同时降低端到端自动化测试用例的比重。
在进行自动化建设时,并不是每种测试都需要自动化,尽量只把执行过程中易出错、烦琐的步骤变成可靠且可重复的自动化步骤。比如,每次测试用户评价都需要先构造一笔真实的订单,那么构造订单和用户评价都属于操作烦琐的步骤。当然对于有些测试内容,人比机器更靠谱,手工测试必不可少,比如体验类、界面类功能等。
另外,在持续发布过程中,还需要在 Staging 和 Prod 环境进行回归。通常,这两个环境因为涉及线上数据库,以自动化的方式在这两个环境写入数据会有比较高的质量风险,因此可以只进行读取操作的自动化,其他内容用手工测试来完成。
在持续交付过程中,对自动化测试有四个关键要求。
要想能做到快速反馈,就需要关键阶段有结果并对结果进行通知。
结果分为两种:构建或部署结果、测试结果。
通知的方式主要通过 IM 或者邮件的方式进行,尽可能做到每一个关键步骤都有通知。对于不满足质量要求的通知,需要有更强烈的通知,比如标红的文字或者多种方式联合通知。
只是通知还不够,很多时候一些不太好的数据需要持续的运营。比如,部署环境总是失败,阻塞了工具链的执行;提测后自动化用例执行失败较多,需要进一步查看是自动化用例稳定性问题、环境稳定性问题还是代码质量问题;这些内容都需要有量化的数据才有利于改进。
用于持续交付的工具有很多,这里不一一列举,借用James Bowman的一张图:
除了图片中的工具,还有很多在持续交付过程中发挥作用的工具:
可以对持续交付过程的工具进行整合的工具有很多,最常用的是 Jenkins,其中尤为推崇 Jenkins 2.x 。
jenkins 1.0 虽然也可以实现自动化构建,但 Jenkins 2.x 的精髓是Pipeline as Code,它能将 project 中的配置信息以 steps 的方式放在一个脚本里,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程,形成流水式发布。
Jenkins Pipeline 脚本示例:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
options {
skipStagesAfterUnstable()
}
stages {
stage('Build') {
steps {
sh 'make'
}
}
stage('Test'){
steps {
sh 'make check'
junit 'reports/**/*.xml'
}
}
stage('Deploy') {
steps {
sh 'make publish'
}
}
}
}
Jenkins Pipeline 可以轻松实现如下所示的持续交付效果:
本节课我首先讲解了持续交付工具链,它是帮助我们把持续交付进行落地的工具集合或自动化平台,用于固化产品交付过程中的各个环节,实现自动化地构建、部署、测试、输出报告等工作。然后讲解了构建持续交付工具链需要进行基础设施盘点、组织支持、关键过程自动化、工具的整合。
接着我讲解了持续交付全流程中的关键过程,如下所述。
最后列举出了可用于持续交付的工具,并且推荐使用 Jenkins 2.x 版本进行这些工具的整合。
你所负责的业务或项目,持续交付工具链是怎样建设的,实现了怎样的效果?请写在留言区里。
相关链接: CI 自动化测试是 DevOps 的基础 https://www.kubernetes.org.cn/7279.html https://insights.thoughtworks.cn/devops-and-continuous-delivery/ 持续交付工具链 Continuous delivery tool landscape: http://www.jamesbowman.me/post/continuous-delivery-tool-landscape/ Jenkins: https://jenkins.io/doc/book/pipeline/